package top.meeting.room.module.system.services.impl;

import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.ehcache.CacheKit;
import top.jfinal.jwtTokenPlugin.kit.JwtKit;
import top.meeting.room.common.constant.ResultEnum;
import top.meeting.room.common.exceptions.HandlerException;
import top.meeting.room.common.kit.ListKit;
import top.meeting.room.module.system.form.ForceForm;
import top.meeting.room.module.system.form.ForceMenuForm;
import top.meeting.room.module.system.form.RootMenuForm;
import top.meeting.room.module.system.form.SonMenuForm;
import top.meeting.room.module.system.model.Force;
import top.meeting.room.module.system.query.ForceQuery;
import top.meeting.room.module.system.services.IForceService;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 我有故事，你有酒么？
 * JKhaled created by yunqisong@foxmail.com 2017/7/22
 * FOR : 权限服务接口实现
 */
public class ForceService implements IForceService {

    public static final IForceService me = new ForceService();

    private ForceService() {
    }

    public Page<Force> pageModel(ForceQuery forceQuery) {
        Page<Force> retVal = null;
        if (forceQuery != null && forceQuery.getPage() != null && forceQuery.getSize() != null) {
            retVal = CacheKit.get(Force.force_pageModel, String.valueOf(forceQuery));
            if (retVal == null) {
                SqlPara sqlPara = Force.dao.getSqlPara(Force.force_pageModel, Kv.by("text", forceQuery.getText()));
                sqlPara.setSql(sqlPara.getSql().replaceFirst(" AND ", " WHERE "));
                retVal = Force.dao.paginate(forceQuery.getPage(), forceQuery.getSize(), sqlPara);
                CacheKit.put(Force.force_pageModel, String.valueOf(forceQuery), retVal);
            }
        }
        return retVal;
    }

    @Override
    public Page<Record> pageRecord(ForceQuery forceQuery) {
        Page<Record> retVal = null;
        if (forceQuery != null && forceQuery.getPage() != null && forceQuery.getSize() != null) {
            retVal = CacheKit.get(Force.force_pageRecord, String.valueOf(forceQuery));
            if (retVal == null) {
                Page<Force> forces = pageModel(forceQuery);
                retVal = new Page<Record>(forces.getList().stream().map(force -> {
                    return force.toBack();
                }).collect(Collectors.toList()), forces.getPageNumber(), forces.getPageSize(), forces.getTotalPage(), forces.getTotalRow());
                CacheKit.put(Force.force_pageRecord, String.valueOf(forceQuery), retVal);
            }
        }
        return retVal;
    }

    public Force getModel(Long id) {
        Force retVal = CacheKit.get(Force.force_getModel, id);
        if (retVal == null) {
            retVal = Force.dao.findById(id);
       //     if (retVal == null) throw new HandlerException(ResultEnum.DATA_ERROR, "找不到要查询的权限");
            CacheKit.put(Force.force_getModel, id, retVal);
        }
        return retVal;
    }

    public Record getRecord(Long id) {
        Record retVal = CacheKit.get(Force.force_getRecord, id);
        if (retVal == null) {
            Force force = Force.dao.findById(id);
            retVal = force.toBack();
            if (retVal == null) throw new HandlerException(ResultEnum.DATA_ERROR, "找不到要查询的权限");
            CacheKit.put(Force.force_getRecord, id, retVal);
        }
        return retVal;
    }


    public Force saveAsModel(ForceForm forceForm) {
        isAllowed(forceForm);
        // 去重
        if (forceForm.getId() == null && findByForceName(forceForm.getForceName()) != null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "添加权限名称不可以为重复");
        String sons = forceForm.getSons();
        if (StrKit.isBlank(forceForm.getSons()) && forceForm.getId() != null) {
            Force temp = Force.dao.findById(forceForm.getId());
            sons = temp == null ? forceForm.getSons() : temp.getSons();
        }
        Force force = new Force()
                .setForceIcon(forceForm.getForceIcon())
                .setForceName(forceForm.getForceName())
                .setForceType(forceForm.getForceType())
                .setForceUrl(forceForm.getForceUrl())
                .setSons(sons);
        if (forceForm.getId() == null) {
            force.save();
        } else {
            force.setId(forceForm.getId()).update();
        }
        if (forceForm.getLevel() == null) {
            force.setLevel(force.getId()).update();
        }
        remove();
        return force;
    }

    public Record saveAsRecord(ForceForm forceForm) {
        Force force = saveAsModel(forceForm);
        return force == null ? null : force.toBack();
    }

    private void isAllowed(ForceForm forceForm) {
        if (forceForm == null || StrKit.isBlank(forceForm.getForceName()))
            throw new HandlerException(ResultEnum.DATA_ERROR, "权限表单数据错误");
    }

    public void deleteById(Long id) {
        deleteByIds(String.valueOf(id));
    }

    public void deleteByIds(String ids) {
        List<Long> idList = ListKit.ids2List(ids);
        if (idList.contains(1L))
            throw new HandlerException(ResultEnum.DATA_ERROR, "不可以删除所有权限");
        SqlPara sqlPara = Db.getSqlPara(Force.force_deleteByIds, Kv.by("ids", idList));
        Db.update(sqlPara.getSql(), sqlPara.getPara());
        remove();
    }

    public Force findByForceName(String forceName) {
        Force force = null;
        if (StrKit.notBlank(forceName)) {
            force = CacheKit.get(Force.force_findByForceName, forceName);
            if (force == null) {
                SqlPara sqlPara = Force.dao.getSqlPara(Force.force_findByForceName, Kv.by("forceName", forceName));
                force = Force.dao.findFirst(sqlPara);
                CacheKit.put(Force.force_findByForceName, forceName, force);
            }
        }
        return force;
    }

    public List<Record> tree() {
        List<Record> retVal = CacheKit.get(Force.force_tree, Force.force_tree);
        if (retVal == null) {
            SqlPara sqlPara = Force.dao.getSqlPara(Force.force_pageModel, Kv.create());
            sqlPara.setSql(sqlPara.getSql().replaceFirst(" AND ", " WHERE "));
            List<Force> forces = Force.dao.find(sqlPara.getSql(), sqlPara.getPara());
            retVal = forces.stream().map(force -> {
                return force.toBack();
            }).collect(Collectors.toList());
            CacheKit.put(Force.force_tree, Force.force_tree, retVal);
        }
        return retVal;
    }

    public Force saveForceMenu(ForceMenuForm forceMenuForm) {
        ForceForm forceForm = ForceForm.builder()
                .id(forceMenuForm.getId())
                .forceName(forceMenuForm.getForceName())
                .forceType(Force.force_button).build();
        Force force = saveAsModel(forceForm);
        Force sonMenu = getModel(forceMenuForm.getSonMenuId());
        if (sonMenu == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "找不到子菜单");
        List<Long> sonList = ListKit.ids2List(sonMenu.getSons());
        if (sonList != null && sonList.contains(force.getId()))
            return force;
        sonList = sonList == null ? new LinkedList<Long>() : sonList;
        sonList.add(force.getId());
        sonMenu.setSons(ListKit.list2Ids(sonList));
        sonMenu.update();
        remove();
        return force;
    }

    public Force saveSonMenu(SonMenuForm sonMenuForm) {
        ForceForm forceForm = ForceForm.builder()
                .id(sonMenuForm.getId())
                .forceName(sonMenuForm.getForceName())
                .forceIcon(sonMenuForm.getForceIcon())
                .forceUrl(sonMenuForm.getForceUrl())
                .forceType(Force.force_menu).build();
        Force force = saveAsModel(forceForm);
        Force rootMenu = getModel(sonMenuForm.getRootMenuId());
        if (rootMenu == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "找不到根菜单");
        List<Long> sonList = ListKit.ids2List(rootMenu.getSons());
        if (sonList != null && sonList.contains(force.getId()))
            return force;
        sonList = sonList == null ? new LinkedList<Long>() : sonList;
        sonList.add(force.getId());
        rootMenu.setSons(ListKit.list2Ids(sonList));
        rootMenu.update();
        remove();
        return force;
    }

    public Force saveRootMenu(RootMenuForm rootMenuForm) {
        ForceForm forceForm = ForceForm.builder()
                .id(rootMenuForm.getId())
                .forceName(rootMenuForm.getForceName())
                .forceIcon(rootMenuForm.getForceIcon())
                .forceUrl(rootMenuForm.getForceUrl())
                .forceType(Force.force_root).build();
        Force force = saveAsModel(forceForm);
        remove();
        return force;
    }

    public void remove() {
        CacheKit.removeAll(Force.force_tree);
        CacheKit.removeAll(Force.force_group);
        CacheKit.removeAll(Force.force_getModel);
        CacheKit.removeAll(Force.force_getRecord);
        CacheKit.removeAll(Force.force_pageModel);
        CacheKit.removeAll(Force.force_sonForces);
        CacheKit.removeAll(Force.force_pageRecord);
        CacheKit.removeAll(Force.force_findByForceName);
        // 更新用户信息
        JwtKit.storeReset();

        RoleService.me.remove();
        UserService.me.remove();
    }
}
